/*
 *   Copyright 2012-present OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

// Packages
import React from 'react';
import axios from 'axios';
import { Intent, Position } from '@blueprintjs/core';

// Actions
import { requestStart, requestSuccess, requestFailure } from './blockUiActions';

// UI
import { BlockUi } from '../components/UI';

// Utils
import { Saiku, Settings } from '../utils';

// Types
import { LOADING_DATASOURCES, SET_DATASOURCES, ADD_CUBE } from './types';

const prefetchDimensions = datasources => dispatch => {
  datasources.forEach(datasource => {
    datasource.catalogs.forEach(catalog => {
      catalog.schemas.forEach(schema => {
        schema.cubes.forEach(cube => {
          const key = `${datasource.name}/${catalog.name}/${
            schema.name === '' || schema.name === null ? 'null' : schema.name
          }/${encodeURIComponent(cube.name)}`;

          dispatch(getDimensions(key));
        });
      });
    });
  });
};

export const getDatasources = () => (dispatch, getState) => {
  const { user } = getState().session;
  const { username } = user;

  dispatch(loadingDatasources());

  axios
    .get(`${Settings.REST_URL}/${username}/discover`)
    .then(res => {
      const { data } = res;

      dispatch(setDatasources(data));
      dispatch(prefetchDimensions(data));
    })
    .catch(error =>
      Saiku.axiosHandleErrors(
        'actions → datasourcesActions.js → getDatasources()',
        error
      )
    );
};

export const getDimensions = key => (dispatch, getState) => {
  const { user } = getState().session;
  const { username } = user;

  axios
    .get(`${Settings.REST_URL}/${username}/discover/${key}/metadata`)
    .then(res => {
      const { data } = res;
      const { dimensions, measures, properties } = data;

      dispatch(
        addCube({ key: `cube.${key}`, dimensions, measures, properties })
      );
    })
    .catch(error =>
      Saiku.axiosHandleErrors(
        'actions → datasourcesActions.js → getDimensions()',
        error
      )
    );
};

export const refreshDatasources = () => (dispatch, getState) => {
  const { user } = getState().session;
  const { username } = user;

  dispatch(requestStart(<BlockUi message="Refreshing cubes..." />));

  axios
    .get(`${Settings.REST_URL}/${username}/discover/refresh`)
    .then(res => {
      const { data } = res;

      dispatch(setDatasources(data));
      dispatch(prefetchDimensions(data));
      dispatch(requestSuccess());

      Saiku.toasts(Position.TOP_RIGHT).show({
        icon: 'tick',
        intent: Intent.SUCCESS,
        message: 'Refreshed Cubes'
      });
    })
    .catch(error => {
      dispatch(requestFailure());
      Saiku.axiosHandleErrors(
        'actions → datasourcesActions.js → refreshDatasources()',
        error
      );
    });
};

export const setDatasources = data => {
  return {
    type: SET_DATASOURCES,
    payload: data
  };
};

export const addCube = data => {
  return {
    type: ADD_CUBE,
    payload: data
  };
};

export const loadingDatasources = () => {
  return {
    type: LOADING_DATASOURCES
  };
};
